
#include "ds1307.h"

#include <stdio.h>
#include "esp_log.h"
static const char *TAG = "ds1307";


#define WRITE_BIT I2C_MASTER_WRITE              /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ                /*!< I2C master read */
#define ACK_CHECK_EN 0x1                        /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0                       /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0                             /*!< I2C ack value */
#define NACK_VAL 0x1                            /*!< I2C nack value */



esp_err_t ds1307_i2c_master_init(void)
{
    int i2c_master_port = DS1307_I2C_CHANNEL;
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = DS1307_MASTER_SDA_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = DS1307_MASTER_SCL_IO,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = DS1307_FREQ_HZ,
        // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
    };
    esp_err_t err = i2c_param_config(i2c_master_port, &conf);
    if (err != ESP_OK) {
        return err;
    }
    return i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);
}

/*  
    @brief set time . default time format is 24hours


*/
esp_err_t ds1307_set_time(uint8_t year,uint8_t month,uint8_t date,uint8_t week,uint8_t hour ,uint8_t minute,uint8_t second)
{
    int ret;
    Rtc_time_typedef time ; 
    time.years.ten_year = year/10;
    time.years.year = year%10;
    time.months.ten_month = month/10;
    time.months.month = month%10;
    time.dates.ten_date = date/10;
    time.dates.date = date%10;
    time.weeks.week = week;
    time.hours.ten_hour = hour/10;
    time.hours.hours = hour%10;
    time.minutes.ten_min = minute/10;
    time.minutes.minutes = minute%10;
    time.seconds.ten_sec = second/10;
    time.seconds.seconds = second%10;
    time.seconds.ch = 0;
    // printf("years value:%d %d %d \r\n",years.value,years.ten_year,years.year);

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, DS1307_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);
    i2c_master_write(cmd,(uint8_t*)&time,7,ACK_CHECK_EN);
    // i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(DS1307_I2C_CHANNEL, cmd, 1000 / portTICK_RATE_MS);   //start to  write I2C
    i2c_cmd_link_delete(cmd);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG,"DS1307 time set failed!");
        return ret;
    }
    else
    {
        // ESP_LOGI(TAG,"DS1307 time set success!");
        return ESP_OK;
    }
}
/* @brief data shoud be a array .lenth should be  7 bytes
    byte  | 0       | 1     |2     |3     |4     |5     |6
    data  |seconds |minutes |hours |weeks |dates |months |year
    data type int8
    @note  size should be 7
    @note year data range  0-99 , should add 2000 to get correct year 

*/

esp_err_t ds1307_read_data( uint8_t * data,uint8_t size)
{
    int ret;
    Rtc_time_typedef time;
    // uint8_t data[8]= {0};
    // uint8_t sec,min,hour,day,date,month,year,data0,data1;
    if(size != 7 )
    {
        ESP_LOGW(TAG,"ds1307 data array size is not 7 ,please set it to 7!!!");
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, DS1307_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);
    // i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(DS1307_I2C_CHANNEL, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG,"DS1307 write failed!");
        return ret;
    }
    vTaskDelay(30 / portTICK_RATE_MS);

    cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, DS1307_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
    // vTaskDelay(1/portTICK_PERIOD_MS);
    if (size >1)
    {
        i2c_master_read(cmd,(uint8_t*)&time,size-1,ACK_VAL);
    }
    
    i2c_master_read_byte(cmd,(uint8_t*)&time+size-1, NACK_VAL);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(DS1307_I2C_CHANNEL, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    data[0] = time.seconds.ten_sec*10 + time.seconds.seconds;
    data[1] = time.minutes.ten_min*10 + time.minutes.minutes;
    data[2] = time.hours.ten_hour*10 + time.hours.hours;
    data[3] = time.weeks.week;
    data[4] = time.dates.ten_date*10 + time.dates.date;
    data[5] = time.months.ten_month*10 + time.months.month;
    data[6] = time.years.ten_year*10 +time.years.year;
    if (ret != ESP_OK) {
        ESP_LOGE(TAG,"DS1307 write failed!");
        return ret;
    }
    // ESP_LOGI(TAG,"DS1307 read success!");
    return ret;
}